﻿using GoogleMobileAds.Api;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace Hotfix
{
    class AdmobAdsEntity
    {
        enum AdsState
        {
            Success,
            LoadFailed,
            ShowFailed
        }

        private RewardedAd rewardedAd;

        public Action completeAction;

        private Queue<int> queueEvents;  //对admob的回调操作

        private float cdTime = 5; //播放失败后的等待时间

        private float preLoadTime;   //上次能加载广告的时间

        public void Init()
        {
            //GoogleMobileAds.GoogleMobileAdsClientFactory.MobileAdsInstance.set
            MobileAds.Initialize(initStatus => { });
            CreateAndLoadRewardedAd();
            queueEvents = new Queue<int>();
        }

        public void Update()
        {
            if (queueEvents != null && queueEvents.Count > 0)
            {
                AdsCallback();
            }
        }

        private void AdsCallback()
        {
            AdsState state = (AdsState)queueEvents.Dequeue();
            switch (state)
            {
                case AdsState.Success:
                    {
                        if (completeAction != null)
                        {
                            completeAction.Invoke();
                            this.CreateAndLoadRewardedAd();
                        }
                        break;
                    }
                case AdsState.LoadFailed:
                    {
                        //Game.EventSystem.Run(EventIdType.SendTip, "load ads failed ");
                        var curTime = UnityEngine.Time.time;
                        if (curTime - preLoadTime > cdTime)
                        {
                            preLoadTime = curTime;
                            this.CreateAndLoadRewardedAd();
                        }
                        break;
                    }
                case AdsState.ShowFailed:
                    {
                        //Game.EventSystem.Run(EventIdType.SendTip, "show ads failed ");
                        break;
                    }
            }

        }

        //使用 OnAdClosed 预加载下一个激励广告
        private void CreateAndLoadRewardedAd()
        {
            string adUnitId = "ca-app-pub-3940256099942544/5224354917"; //测试广告id

            this.rewardedAd = new RewardedAd(adUnitId);
            // Called when an ad request has successfully loaded.
            this.rewardedAd.OnAdLoaded += HandleRewardedAdLoaded;
            // Called when an ad request failed to load.
            this.rewardedAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;
            // Called when an ad is shown.
            this.rewardedAd.OnAdOpening += HandleRewardedAdOpening;
            // Called when an ad request failed to show.
            this.rewardedAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;
            // Called when the user should be rewarded for interacting with the ad.
            this.rewardedAd.OnUserEarnedReward += HandleUserEarnedReward;
            // Called when the ad is closed.
            this.rewardedAd.OnAdClosed += HandleRewardedAdClosed;

            // Create an empty ad request.
            AdRequest request = new AdRequest.Builder()
                                .TagForChildDirectedTreatment(true)
                                .AddExtra("tag_for_under_age_of_consent", "true")
                                .Build();
            // Load the rewarded ad with the request.
            this.rewardedAd.LoadAd(request);
        }

        private AdRequest CreateAdRequest()
        {
            return new AdRequest.Builder()
                .AddTestDevice(AdRequest.TestDeviceSimulator)
                .AddTestDevice("0123456789ABCDEF0123456789ABCDEF")
                .AddKeyword("game")
                .SetGender(Gender.Male)
                .SetBirthday(new DateTime(1985, 1, 1))
                .TagForChildDirectedTreatment(false)
                .AddExtra("color_bg", "9B30FF")
                .Build();
        }

        public bool CheckAdsAlreay()
        {
            if (this.rewardedAd != null)
            {
                bool result = rewardedAd.IsLoaded();
                if (result == false)
                {
                    var curTime = UnityEngine.Time.time;
                    if (curTime - preLoadTime > cdTime)
                    {
                        preLoadTime = curTime;
                        this.CreateAndLoadRewardedAd();
                    }
                }
            }
            else
            {
                var curTime = UnityEngine.Time.time;
                if (curTime - preLoadTime > cdTime)
                {
                    preLoadTime = curTime;
                    this.CreateAndLoadRewardedAd();
                }
                else
                {
                    return false;
                }
            }
            return this.rewardedAd.IsLoaded();
        }

        public void UserChoseToWatchAd()
        {
            if (this.rewardedAd.IsLoaded())
            {
                this.rewardedAd.Show();
            }
        }

        //在广告加载完成时被调用。
        public void HandleRewardedAdLoaded(object sender, EventArgs args)
        {
            Debug.Log("广告加载完成");
        }

        //在广告加载失败时被调用
        public void HandleRewardedAdFailedToLoad(object sender, AdErrorEventArgs args)
        {
            Debug.Log("广告加载失败时: " + args.Message);
            queueEvents.Enqueue((int)AdsState.LoadFailed);
        }

        //在广告开始展示并铺满设备屏幕时被调用。如需暂停应用音频输出或游戏循环，则非常适合使用此方法。
        public void HandleRewardedAdOpening(object sender, EventArgs args)
        {
            Debug.Log("广告开始展示并铺满设备屏幕时被调用");
        }

        //在广告显示失败时被调用
        public void HandleRewardedAdFailedToShow(object sender, AdErrorEventArgs args)
        {
            Debug.Log("广告显示失败时被调用: " + args.Message);
            queueEvents.Enqueue((int)AdsState.ShowFailed);
        }

        //在用户因观看视频而应获得奖励时被调用。 Reward 参数描述了要呈现给用户的奖励。
        public void HandleRewardedAdClosed(object sender, EventArgs args)
        {
            Debug.Log("观看视频而应获得奖励时被调用");
            queueEvents.Enqueue((int)AdsState.Success);
        }

        //在用户点按“关闭”图标或使用“返回”按钮关闭激励视频广告时被调用。如果您的应用暂停了音频输出或游戏循环，则非常适合使用此方法恢复这些活动。
        public void HandleUserEarnedReward(object sender, Reward args)
        {
            string type = args.Type;
            double amount = args.Amount;
            Debug.Log("用户点按“关闭”图标或使用“返回”按钮关闭激励视频广告时被调用 " + amount.ToString() + " " + type);
        }

        public void SetCompleteAction(Action complete)
        {
            completeAction = complete;
        }
    }

}

